#!/usr/bin/env python
# encoding: utf-8


"""
@file: xiangxian.py
@time: 2016/11/3 下午2:25
"""
# 判断象限的问题
from sympy import solveset
from mathsolver.functions.base import *
from mathsolver.functions.sanjiao import Jiao as jiao
from mathsolver.functions.sanjiao import sanjiao_utils as su
from mathsolver.functions.budengshi import common_opers as co
from mathsolver.functions.sanjiao.Jiao import trig_f_quad_pm, quad_interval
from operator import itemgetter
from mathsolver.functions.sanjiao.sanjiao_constants import QUADRANT_SEARCH_SUFFIX


def angle_quads(intl):
    if isinstance(intl, Interval):
        return FiniteSet(*jiao.angle_interval_quad(intl))
    else:
        intls = intl.args
        quads = []
        for i in intls:
            quads.extend(jiao.angle_interval_quad(i))
        return FiniteSet(*quads)


# Input1 BaseIneq:不等式
# Input2 BaseIneqs:不等式组
# 若cosα<0,tanα<0,则α是第()象限角.
class XiangXian001(BaseFunction):
    def solver(self, *args):
        self.label.add('三角函数象限')
        if len(args) != 1:
            raise Exception('Type Match Error')
        if isinstance(args[0], BaseIneqs):
            ineqs = args[0].sympify()
        elif isinstance(args[0], BaseIneq):
            ineqs = [args[0].sympify()]
        else:
            raise Exception("to do")
        quad_set = S.Reals
        variable = co.ineqs_symbs(ineqs)[0]
        for ineq in ineqs:
            trig_mon, ineq_op, r = su.stand_trig_ineq(BaseIneq(ineq)).sympify()
            t_coef, t_type, t_arg, t_const = su.simp_trig_info(trig_mon)
            quad_pms = trig_f_quad_pm(t_type)
            quad_pms = filter(
                lambda _: solveset(str(sympify(t_coef) * _[1]) + ineq_op + str(r), domain=S.Reals) == S.Reals,
                enumerate(quad_pms, start=1))
            quads = map(itemgetter(0), quad_pms)
            self.steps.append(['因为' + BaseIneq(ineq).printing() + ',',
                               '%s 在 %s 象限' % (new_latex(variable), new_latex(quads))])
            quad_set = quad_set.intersect(FiniteSet(*quads))
        self.steps.append(['\therefore 角%s 是 %s象限角' % (new_latex(variable), new_latex(quad_set)), ''])
        self.output.append(BaseSymbolValue({variable: quad_set}))
        return self


# 已知α为第三象限角，则α/2所在的象限是
# Input1 paramer1:α的区间; paramer2:α的表达式 比如α/2
# Input2 paramer1:α/2[此时要搜寻α的取值范围]
class XiangXian002(BaseFunction):
    def solver(self, *args):
        if len(args) == 2 and isinstance(args[0], BaseInter) and isinstance(args[1], BasePoly):  # Input1
            angle_expr = args[1].sympify()
            angle_symb = list(angle_expr.free_symbols)[0]
            angle_coeff = angle_expr.coeff(angle_symb)
            angle_interval = args[0].interval
            expr_interval = Interval(angle_interval.left * angle_coeff, angle_interval.right * angle_coeff,
                                     left_open=angle_interval.left_open, right_open=angle_interval.right_open)
            expr_quads = angle_quads(expr_interval)
            self.steps.append([new_latex(angle_expr), '为%s象限' % new_latex(expr_quads)])
            self.output.append(BaseSymbolValue({angle_symb: expr_quads}))
        elif len(args) == 1 and isinstance(args[0], BasePoly):
            angle_expr = args[0].sympify()
            angle_symb = list(angle_expr.free_symbols)[0]
            angle_coeff = angle_expr.coeff(angle_symb)
            angle_quad_searc_key = sympify(str(angle_symb) + QUADRANT_SEARCH_SUFFIX)
            if self.search(angle_quad_searc_key):
                angle_quad_value = self.search(angle_quad_searc_key)
                if isinstance(angle_quad_value, FiniteSet):
                    angle_quad_value = list(angle_quad_value)[0]
                angle_interval = quad_interval(angle_quad_value)
                expr_interval = Interval(angle_interval.left * angle_coeff, angle_interval.right * angle_coeff,
                                         left_open=angle_interval.left_open, right_open=angle_interval.right_open)
                expr_quads = angle_quads(expr_interval)
                self.steps.append([new_latex(angle_expr), '为%s象限' % new_latex(expr_quads)])
                self.output.append(BaseSymbolValue({angle_symb: expr_quads}))
            else:
                raise Exception('Type Match Error')
        else:
            raise Exception('Type Match Error')
        return self


class XiangXian(BaseFunction):
    CLS = [XiangXian001, XiangXian002]

    def solver(self, *args):
        solve_r = None
        for cl in XiangXian.CLS:
            try:
                solve_r = cl(verbose=True)
                solve_r.known = self.known
                solve_r = solve_r.solver(*args)
                solve_r.label.add('求角的象限')
                break
            except Exception:
                solve_r = None
        if not solve_r:
            raise 'try fail'
        return solve_r


if __name__ == '__main__':
    pass
